#include "CFileSystem.h"
#include <QDebug>


//====================================================================================
//      Class CFrame Implementation
//====================================================================================

//_________________________________________________________________________
CFrame::CFrame (int bufferSize)
{
    if (bufferSize>0)
    {
        m_BufferSize = bufferSize;
        m_buffer = new BYTE[m_BufferSize];
    }
    else
    {
        m_BufferSize = 0;
        m_buffer = NULL;
    }
}

//_________________________________________________________________________
CFrame::CFrame (CFrame& frame)
{
    // Cleanup
    if (m_BufferSize>0)
    {
        if (m_buffer != NULL)
            delete []m_buffer;
        m_BufferSize = 0;
    }

    if (frame.m_BufferSize>0)
    {
        m_BufferSize = frame.m_BufferSize;
        m_buffer = new BYTE[m_BufferSize];

        for (int i= 0; i<m_BufferSize; i++)
        {
            m_buffer[i] = frame.m_buffer[i];
        }
    }
}

//_________________________________________________________________________
CFrame::~CFrame ()
{
    if (m_buffer != NULL)
        delete []m_buffer;
    m_BufferSize = 0;
}

//_________________________________________________________________________
void CFrame::SetData(int bufferSize, BYTE* buffer)
{
    if (m_BufferSize>0)
    {
        if (m_buffer != NULL)
            delete []m_buffer;
        m_BufferSize = 0;
    }

    if (bufferSize>0)
    {
        m_BufferSize = bufferSize;
        m_buffer = new BYTE[m_BufferSize];

        memcpy (m_buffer, buffer, bufferSize);
    }
}

//_________________________________________________________________________
int CFrame::NumOfBytes ()
{
    return m_BufferSize;
}


//====================================================================================
//      Class CFile Implementation
//====================================================================================


//_________________________________________________________________________
CFile::CFile()
{
    m_HWParams = NULL;
    m_Duration = 255;
    m_FileName = NULL;
    m_BlockList = NULL;
    m_NumOfFrames = 0;
    m_Buffers = NULL;
    m_TableNeedsUpdate = 0;
    m_ContentsAvailable = 1;
    m_isDownloading = 0;
    m_originalImage = NULL;
}

//_________________________________________________________________________
CFile::CFile(CHardwareParams* hwParams,
      char *fileName,
      int duration)
{
    m_HWParams = hwParams;
    m_Duration = (WORD)(duration&0xffff);

    m_FileName = new char[m_HWParams->FilenameLength];
    if (strlen(fileName)==0)
    {
        strcpy(m_FileName, "new_file\0");
    }
    else if ( ((int)(strlen(fileName))) > (m_HWParams->FilenameLength-1) )
    {
        strncpy(m_FileName, fileName, m_HWParams->FilenameLength);
        m_FileName[m_HWParams->FilenameLength-1]='\0';
    }
    else
    {
        strcpy(m_FileName, fileName);
    }

    m_BlockList = new WORD[m_HWParams->FileMaxNumberOfFrames];
    for (int i=0; i<m_HWParams->FileMaxNumberOfFrames; i++)
        m_BlockList[i]=0xffff;

    m_NumOfFrames = 0;
    m_Buffers = NULL;
    m_TableNeedsUpdate = 1;
    m_ContentsAvailable = 1;
    m_isDownloading = 0;

    m_originalImage = NULL;
}

//_________________________________________________________________________
CFile::CFile(const CFile& file)
{
    m_HWParams = file.m_HWParams;
    m_Duration = file.m_Duration;

    m_FileName = new char[m_HWParams->FilenameLength];
    strcpy(m_FileName,file.m_FileName);

    m_BlockList = new WORD[m_HWParams->FileMaxNumberOfFrames];
    memcpy (m_BlockList, file.m_BlockList, m_HWParams->FileMaxNumberOfFrames*sizeof(WORD));

    m_NumOfFrames = file.m_NumOfFrames;
    m_Buffers = new CFrame[m_NumOfFrames];      // Currently the size is 0

    m_TableNeedsUpdate = file.m_TableNeedsUpdate;

    m_ContentsAvailable = file.m_ContentsAvailable;

    m_Reserved = file.m_Reserved;

    if (m_ContentsAvailable)
    {
        for (int i=0; i<m_NumOfFrames; i++)
        {
            m_Buffers[i].SetData(file.m_Buffers[i].m_BufferSize,file.m_Buffers[i].m_buffer);
        }
    }

    m_ContentsAvailable = file.m_ContentsAvailable;
    m_isDownloading = file.m_isDownloading;

//    if (file.m_originalImage!=NULL)
//        m_originalImage = new QImage(*file.m_originalImage);
    m_originalImage = NULL;
}

//_________________________________________________________________________
CFile::~CFile()
{
    delete []m_FileName;

    if (m_BlockList != NULL)
        delete []m_BlockList;

    if (m_Buffers != NULL)
        delete []m_Buffers;

    if (m_originalImage!=NULL)
        delete m_originalImage;
}

//_________________________________________________________________________
void CFile::SetData(CHardwareParams* hwParams,
                   char *fileName,
                   int duration)
{
    m_HWParams = hwParams;
    m_Duration = (WORD)(duration&0xffff);

    if (m_FileName!=NULL)
        delete []m_FileName;

    m_FileName = new char[m_HWParams->FilenameLength];
    if (strlen(fileName)==0)
    {
        strcpy(m_FileName, "new_file\0");
    }
    else if ( ((int)(strlen(fileName))) > (m_HWParams->FilenameLength-1) )
    {
        strncpy(m_FileName, fileName, m_HWParams->FilenameLength);
        m_FileName[m_HWParams->FilenameLength-1]='\0';
    }
    else
    {
        strcpy(m_FileName, fileName);
    }

    if (m_BlockList!=NULL)
        delete []m_BlockList;

    m_BlockList = new WORD[m_HWParams->FileMaxNumberOfFrames];

    m_TableNeedsUpdate = 1;

    m_isDownloading = 0;
}

//_________________________________________________________________________
int CFile::FileSize()
{
    int iCount = 0;

    for (int i=0; i<m_NumOfFrames; i++)
    {
        iCount += m_Buffers[i].NumOfBytes();
    }

    iCount += m_HWParams->FilenameLength;               // Bytes
    iCount += m_HWParams->FileMaxNumberOfFrames*2;      // Words
    iCount += 4;                                        // Word - num of frames; Byte - duration; Byte - reserved

    return iCount;
}

//_________________________________________________________________________
int CFile::AddFrame(int blockNumber, CFrame &frame)
{
    if (blockNumber < 0)
    {
        return FILE_SYSTEM_ILLEGAL_MEMORY_BLOCK;
    }

    if (m_NumOfFrames==m_HWParams->FileMaxNumberOfFrames)    // we reached to the maximal frame count for the file
    {
        return FILE_SYSTEM_MAX_FRAME_REACHED_ERROR;
    }

    m_BlockList[m_NumOfFrames++] = blockNumber;
    CFrame* newFrame = new CFrame[m_NumOfFrames];

    for (int i=0; i<m_NumOfFrames-1; i++)
    {
        newFrame[i].SetData(m_Buffers[i].m_BufferSize, m_Buffers[i].m_buffer);
    }

    if (frame.m_BufferSize>(m_HWParams->FlashBlockSizeBytes*m_HWParams->NumOfBlocksForFrame))
        newFrame[m_NumOfFrames-1].SetData((m_HWParams->FlashBlockSizeBytes*m_HWParams->NumOfBlocksForFrame), frame.m_buffer);
    else newFrame[m_NumOfFrames-1].SetData(frame.m_BufferSize, frame.m_buffer);

    delete []m_Buffers;
    m_Buffers = newFrame;

    m_TableNeedsUpdate = 1;
    m_ContentsAvailable = 1;
    m_isDownloading = 0;
    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFile::AddFrame(int blockNumber, BYTE* buffer, int bufferSize)
{
    CFrame newFrame(0);
    newFrame.SetData(bufferSize, buffer);

    return AddFrame(blockNumber, newFrame);
}

//_________________________________________________________________________
int CFile::DeleteLastFrame()
{
    if (m_NumOfFrames==0)
    {
        return FILE_SYSTEM_NO_FRAMES_WERE_FOUND_ERROR;
    }

    m_NumOfFrames--;

    CFrame* newFrame = new CFrame[m_NumOfFrames];
    for (int i=0; i<m_NumOfFrames; i++)
    {
        newFrame[i].SetData(m_Buffers[i].m_BufferSize, m_Buffers[i].m_buffer);
    }

    delete []m_Buffers;
    m_Buffers = newFrame;

    m_TableNeedsUpdate = 1;
    m_isDownloading = 0;
    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFile::SetFrameData(int frameIndex, BYTE* buffer, int bufferSize)
{
    if (frameIndex>=m_NumOfFrames || frameIndex<0)
    {
        return FILE_SYSTEM_NO_FRAMES_WERE_FOUND_ERROR;
    }

    m_Buffers[frameIndex].SetData(bufferSize, buffer);
    m_isDownloading = 0;

    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
void CFile::InvalidateTable()
{
    m_TableNeedsUpdate = 1;
}

void CFile::IntermediateValidateTable()
{
    m_TableNeedsUpdate = 2;
}

//_________________________________________________________________________
int CFile::GetValidity()
{
    if (m_TableNeedsUpdate==1)
        return 0;
    if (m_TableNeedsUpdate==2)
        return 2;

    return 1;
}

//_________________________________________________________________________
int CFile::GetFrameData(int frameNum, int* length, unsigned char **data)
{
    if (frameNum>=m_NumOfFrames)
    {
        return FILE_SYSTEM_FRAME_DOESNT_EXIST;
    }

    *length = m_Buffers->NumOfBytes();
    *data = m_Buffers->m_buffer;

    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFile::GetEntrySize()
{
    return (m_HWParams->GetEntrySize ());
}

//_________________________________________________________________________
bool CFile::operator==(const CFile& file)
{
    return (!strcmp(m_FileName, file.m_FileName));
}

//_________________________________________________________________________
int CFile::GetNumOfFrames ( void )
{
    return m_NumOfFrames;
}

//_________________________________________________________________________
void CFile::SetDownloadingState ( int downloading )
{
    m_isDownloading = downloading;
}

//_________________________________________________________________________
int CFile::GetDownloadingState ( void )
{
    return m_isDownloading;
}

//_________________________________________________________________________
void CFile::setOriginalImage (QImage& image)
{
    if (m_originalImage!=NULL)
        delete m_originalImage;

    m_originalImage = new QImage(image);
}

//_________________________________________________________________________
QImage* CFile::getOriginalImage ( void )
{
    return m_originalImage;
}

//====================================================================================
//      Class CFileSystem Implementation
//====================================================================================

//_________________________________________________________________________
CFileSystem::CFileSystem(CHardwareParams *hwParams)
{
    m_HWParams = hwParams;
    m_MemorySizeBytes = (hwParams->MemorySize)*1024*1024/8;                                   // Bytes
    m_MaxFileSize = (hwParams->FlashBlockSizeBytes)*(hwParams->NumOfBlocksForFrame); // Bytes

    if (m_MaxFileSize!= 0)
        m_MaxFiles = m_MemorySizeBytes/m_MaxFileSize-2; // Leave at least one file size at the end for entry table
    m_EntryTableStartAddress = m_MaxFiles*m_MaxFileSize;        // Byte address
    m_Files.empty();                           // Set file list to empty

    m_MemVac = new int[m_MaxFiles];

    for (int i = 0; i < m_MaxFiles; i ++ )
        m_MemVac[i] = FILE_SYSTEM_MEMVAC_EMPTY;                   // All set to available
}

//_________________________________________________________________________
CFileSystem::CFileSystem(const CFileSystem& fs)
{
    m_HWParams = fs.m_HWParams;
    m_MemorySizeBytes = fs.m_MemorySizeBytes;
    m_MaxFiles = fs.m_MaxFiles;
    m_MaxFileSize = fs.m_MaxFileSize;
    m_EntryTableStartAddress = fs.m_EntryTableStartAddress;
    m_Files = fs.m_Files;
    m_MemVac = new int[fs.m_MaxFiles];

    memcpy(m_MemVac, fs.m_MemVac, fs.m_MaxFiles);
}

//_________________________________________________________________________
CFileSystem::~CFileSystem()
{
    if (m_MemVac!=NULL)
        delete []m_MemVac;

    m_MemVac = NULL;
}

//_________________________________________________________________________
void CFileSystem::DeleteFileSystemData()
{
    m_Files.empty();

    for (int i = 0; i < m_MaxFiles; i ++ )
        m_MemVac[i] = FILE_SYSTEM_MEMVAC_EMPTY;                   // All set to available
}

//_________________________________________________________________________
CFile* CFileSystem::SearchFile(char* filename, list<CFile>::iterator* fileIt)
{
    list<CFile>::iterator file;

    for (file = m_Files.begin(); file!=m_Files.end(); file++)
    {
        if (!strncmp(filename, file->m_FileName,
                     ((int)(strlen(filename))>=m_HWParams->FilenameLength)?(m_HWParams->FilenameLength-1):(strlen(filename))))
        {
            if (fileIt != NULL)
                *fileIt = file;
            return &(*file);
        }
    }

    return NULL;        // File Not Found
}

//_________________________________________________________________________
int CFileSystem::AddFile(char* filename, int param)
{
    // Search for a file with the same name
    if (SearchFile(filename)!=NULL)
    {
        return FILE_SYSTEM_FILE_ALREADY_EXISTS_ERROR;
    }

    CFile newFile(m_HWParams, filename);
    newFile.m_Reserved = param;

    m_Files.push_back(newFile);

    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFileSystem::AddFile(CFile file)
{
    // Search for a file with the same name
    if (SearchFile(file.m_FileName)!=NULL)
    {
        return FILE_SYSTEM_FILE_ALREADY_EXISTS_ERROR;
    }

    CFile newFile(file);

    m_Files.push_back(newFile);

    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFileSystem::DeleteFileFS(char* filename)
{
    list<CFile>::iterator fileIt;
    CFile* file = SearchFile(filename, &fileIt);
    if (file==NULL)
    {
        return FILE_SYSTEM_FILE_NOT_FOUND_ERROR;
    }

    for (int i = 0; i<(*fileIt).m_NumOfFrames; i++)
    {
        m_MemVac[(*fileIt).m_BlockList[i]] = FILE_SYSTEM_MEMVAC_DELETED;
    }

    m_Files.remove(*fileIt);

    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFileSystem::AddFrameToFile(char* filename, CFrame& frame)
{
    list<CFile>::iterator fileIt;
    CFile* file = SearchFile(filename, &fileIt);
    if (file==NULL)
    {
        return FILE_SYSTEM_FILE_NOT_FOUND_ERROR;
    }

    int blockNumber = FindMemorySlot(FILE_SYSTEM_FIND_FOR_NEW_SLOT);

    return (*fileIt).AddFrame(blockNumber, frame);
}

//_________________________________________________________________________
int CFileSystem::AddFrameToFile(char* filename, int bufferSize, BYTE* buffer)
{
    CFrame newFrame(bufferSize);
    newFrame.SetData(bufferSize, buffer);

    return AddFrameToFile(filename, newFrame);
}

//_________________________________________________________________________
void CFileSystem::SetOriginalImageToFile (char* filename, QImage& image)
{
    list<CFile>::iterator fileIt;
    CFile* file = SearchFile(filename, &fileIt);
    if (file==NULL)
    {
        return;
    }

    (*fileIt).setOriginalImage(image);
}

//_________________________________________________________________________
QImage* CFileSystem::GetOriginalImageToFile (char* filename)
{
    list<CFile>::iterator fileIt;
    CFile* file = SearchFile(filename, &fileIt);
    if (file==NULL)
    {
        return NULL;
    }

    return (*fileIt).getOriginalImage();
}

//_________________________________________________________________________
int CFileSystem::SetFileDuration(char* filename, int duration)
{
    CFile* file = SearchFile(filename);
    if (file==NULL)
    {
        return FILE_SYSTEM_FILE_NOT_FOUND_ERROR;
    }

    file->m_Duration = duration;
    file->InvalidateTable();

    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFileSystem::SuggestFilename(char* wantedFilename, char* suggestedFilename)
{
    if (strlen(wantedFilename)==0)
    {
        return FILE_SYSTEM_ILLEGAL_FILE_NAME;
    }
    else
    {
        int N = ((int)(strlen(wantedFilename))<(m_HWParams->FilenameLength))?(strlen(wantedFilename)):((m_HWParams->FilenameLength-1));
        strncpy(suggestedFilename, wantedFilename, N );
        suggestedFilename[N] = '\0';
    }

    int count = 0;

    while (SearchFile(suggestedFilename)!=NULL && count<10)
    {
        suggestedFilename[strlen(suggestedFilename)-1]='0'+(count++);
    }

    if (SearchFile(suggestedFilename)==NULL)       // if we found somehow a valid filename
    {
        if (count == 0)
            return FILE_SYSTEM_NO_ERROR;
        else
            return FILE_SYSTEM_RECOVERRED_FROM_NONUNIQUE;
    }

    return FILE_SYSTEM_COULDNT_RECOVER_NONUNIQUE;
}

//_________________________________________________________________________
int CFileSystem::ChangeFileName (char* oldFilename, char* newFilename)
{
    char temp[1024];

    CFile* file = SearchFile(oldFilename);

    if (file==NULL)
    {
        return FILE_SYSTEM_FILE_NOT_FOUND_ERROR;
    }

    if (SuggestFilename(newFilename, temp)!=FILE_SYSTEM_COULDNT_RECOVER_NONUNIQUE)
    {
        file->InvalidateTable();
        strcpy(file->m_FileName, temp);
        return FILE_SYSTEM_NO_ERROR;
    }

    return FILE_SYSTEM_COULDNT_RECOVER_NONUNIQUE;
}

//_________________________________________________________________________
int CFileSystem::DeleteLastFrameFromFile(char* filename)
{
    return FILE_SYSTEM_NO_ERROR;
}

//_________________________________________________________________________
int CFileSystem::FindMemorySlot(FILE_SYSTEM_FIND_PURPOSE_EN purpose)
{
    if (purpose == FILE_SYSTEM_FIND_FOR_NEW_SLOT)
    {
        for (int i=0; i<m_MaxFiles; i++)
        {
            if (m_MemVac[i]==FILE_SYSTEM_MEMVAC_EMPTY ||
                m_MemVac[i]==FILE_SYSTEM_MEMVAC_DELETED)
            {
                m_MemVac[i]=FILE_SYSTEM_MEMVAC_OVERWRITTEN;
                return i;
            }
        }
    }
    else
    {
        return -1;
    }

    return -1;
}

//_________________________________________________________________________
file_list_t& CFileSystem::GetFileList()
{
    return m_Files;
}

//_________________________________________________________________________
int CFileSystem::GetFileFrameData(char* filename, int frameNum, int *length, unsigned char** data)
{
    CFile* file = SearchFile(filename);

    if (file==NULL)
    {
        return FILE_SYSTEM_FILE_NOT_FOUND_ERROR;
    }

    return (file->GetFrameData(frameNum, length, data));
}

//_________________________________________________________________________
int CFileSystem::ParseFromRawFS(BYTE* data, int length)
{
    int i;
    BYTE* itr = data;
    int count = length;
    m_Files.empty();

    qDebug ("Creating an empty memvac vector, length: %d\n", m_MaxFiles);
    for (int i = 0; i < m_MaxFiles; i ++ )
        m_MemVac[i] = FILE_SYSTEM_MEMVAC_EMPTY;                   // All set to available

    if ( strncmp((char*)(itr), "EMPTY", strlen("EMPTY"))==0 )            // Our filesystem is empty
    {
        qDebug ("The file system is empty.");
        return 0;
    }

    char *filename = new char[m_HWParams->FilenameLength+1];
    WORD *blockList = new WORD[m_HWParams->FileMaxNumberOfFrames];

    int entrySizeBytes = sizeof(WORD) +                                     // uint16_t 	iNumFrames;
                         m_HWParams->FilenameLength +                       // char		sFileName[FS_FILENAME_LENGTH];
                         m_HWParams->FileMaxNumberOfFrames*sizeof(WORD) +   // uint16_t 	iBlockList[FS_FILE_MAX_FRAMES];
                         sizeof(BYTE) +                                     // uint8_t	iDuration;
                         sizeof(BYTE) ;                                     // uint8_t      iReserved/iWidth;

    // the length is not alligned to entry size
    if (length%entrySizeBytes!=0)
        return -1;

    while (count)
    {
        qDebug ("Parsing file number %d:", count/entrySizeBytes);
        WORD iNumFrames = *((WORD*)(itr));
        qDebug ("   Number of frames: %d.", iNumFrames);
        BYTE iDuration = *((WORD*)(itr + sizeof(WORD) + m_HWParams->FilenameLength + m_HWParams->FileMaxNumberOfFrames*sizeof(WORD)));
        qDebug ("   Duration: %d.", iDuration);
        BYTE iReserved = *((WORD*)(itr + sizeof(WORD) + m_HWParams->FilenameLength + m_HWParams->FileMaxNumberOfFrames*sizeof(WORD) + sizeof(BYTE)));
        qDebug ("   Reserved: %d.", iReserved);
        memcpy(filename, itr + sizeof(WORD), m_HWParams->FilenameLength);
        filename[m_HWParams->FilenameLength] = '\0';
        qDebug ("   File name: %s.", filename);
        memcpy(blockList, itr + sizeof(WORD) + m_HWParams->FilenameLength, sizeof(WORD)*m_HWParams->FileMaxNumberOfFrames);

        for (int k=0; k<m_HWParams->FileMaxNumberOfFrames; k++)
        {
            if (k<iNumFrames)
                qDebug ("   BlockList[%d] (USED): %d.", k, blockList[k]);
            else
                qDebug ("   BlockList[%d] (UN-USED): %d.", k, blockList[k]);

        }

        CFile file(m_HWParams, filename, iDuration);
        file.m_NumOfFrames = iNumFrames;
        file.m_Reserved = iReserved;

        qDebug ("Assigning block list to memvac array\n");
        for (i = 0; i < iNumFrames; i++)
        {
            file.m_BlockList[i] = blockList[i];
            qDebug(" %d. block number %d\n",i,blockList[i]);
            if (blockList[i]>m_MaxFiles)
            {
                // there is a problem here
                qDebug ("FileSystem parsing error - block list [%d] = %d.\n", i, blockList[i]);

            }
            else
            {
                m_MemVac[file.m_BlockList[i]] = FILE_SYSTEM_MEMVAC_USED;
                file.m_TableNeedsUpdate = 0;
            }
        }


        file.m_ContentsAvailable = 0;       // not all the data was downloaded yet

        AddFile(file);

        count -= entrySizeBytes;
        itr += entrySizeBytes;
    }

    delete []filename;
    delete []blockList;

    SetAllFilesSynchronized (  );

    return 0;
}

//_________________________________________________________________________
// Please free the memory after usage
int CFileSystem::GetEntryTableData(int *length, unsigned char ** data)
{
    file_list_it_t file;
    int dataLen = m_HWParams->GetEntrySize ()*m_Files.size ();
    char debugFilename[1024] = {0};

    qDebug ("GetEntryTableData:");
    qDebug("dataLen: %d; single  entry length: %d", dataLen, m_HWParams->GetEntrySize ());

    int offset = 0, innerOffset = 0;

    *data = new unsigned char[dataLen];
    *length = dataLen;

    for (file = m_Files.begin(), offset = 0; file!=m_Files.end(); file++, offset+=m_HWParams->GetEntrySize())
    {
        qDebug ("       File Number: %d", offset/m_HWParams->GetEntrySize());
        innerOffset = 0;

        memcpy (*data+offset + innerOffset, &file->m_NumOfFrames, sizeof (WORD));
        qDebug ("       Num of frames: %d", file->m_NumOfFrames);
        innerOffset += sizeof(WORD);
        memcpy (*data+offset + innerOffset, file->m_FileName, m_HWParams->FilenameLength);
        memcpy (debugFilename, file->m_FileName, m_HWParams->FilenameLength);
        debugFilename[m_HWParams->FilenameLength] = '\0';
        qDebug ("       File name: %s", debugFilename);
        innerOffset += m_HWParams->FilenameLength;
        memcpy (*data+offset + innerOffset, file->m_BlockList, m_HWParams->FileMaxNumberOfFrames*sizeof(WORD));
        for (int i=0; i<m_HWParams->FileMaxNumberOfFrames; i++)
        {
            if (i<file->m_NumOfFrames)
                qDebug ("       Block number [USED]: %d", file->m_BlockList[i]);
            else
                qDebug ("       Block number [NOT USED]: %d", file->m_BlockList[i]);
        }

        innerOffset += m_HWParams->FileMaxNumberOfFrames*sizeof(WORD);
        memcpy (*data+offset + innerOffset, &file->m_Duration, sizeof(BYTE));
        qDebug ("       Duration: %d", file->m_Duration);
        innerOffset += sizeof(BYTE);
        memcpy (*data+offset + innerOffset, &file->m_Reserved, sizeof(BYTE));
        qDebug ("       Reserved: %d", file->m_Reserved);
    }

    return 0;
}

//_________________________________________________________________________
int CFileSystem::GetEntryTableStartAddress ()
{
    return m_EntryTableStartAddress;
}

//_________________________________________________________________________
int CFileSystem::GetNumOfFiles ( void )
{
    return m_Files.size ();
}

//_________________________________________________________________________
file_list_it_t CFileSystem::GetFileFromIndex ( int fileIndex )
{
    int i = fileIndex;
    file_list_it_t file = m_Files.begin ();


    if (fileIndex < 0)
        return file;

    if ( fileIndex >= GetNumOfFiles() )
        return file;


    while (i--)
        file++;

    return file;
}

//_________________________________________________________________________
FILE_SYSTEM_MEMVAC_STATUS_EN CFileSystem::GetMemVec(int index)
{
    return (FILE_SYSTEM_MEMVAC_STATUS_EN)(m_MemVac[index]);
}

//_________________________________________________________________________
void CFileSystem::SetAllFilesSynchronized ( void )
{
    file_list_it_t file = m_Files.begin ();
    int i;

    for ( ; file != m_Files.end (); file ++)
    {
        file->m_TableNeedsUpdate = 0;
    }

    for (i = 0 ; i<m_MaxFiles; i++)
    {
        if (m_MemVac[i] == FILE_SYSTEM_MEMVAC_EMPTY || m_MemVac[i] == FILE_SYSTEM_MEMVAC_DELETED)
            m_MemVac[i] = FILE_SYSTEM_MEMVAC_EMPTY;
        else m_MemVac[i] = FILE_SYSTEM_MEMVAC_USED;
    }
}
